package com.cskaoyan.shopping.service.impl;

import com.cskaoyan.mall.commons.constant.SysRetCodeConstants;
import com.cskaoyan.mall.commons.exception.ExceptionProcessorUtils;
import com.cskaoyan.mall.commons.exception.ValidateException;
import com.cskaoyan.mall.constant.ShoppingRetCode;
import com.cskaoyan.mall.dto.ClearCartItemRequest;
import com.cskaoyan.mall.dto.ClearCartItemResponse;
import com.cskaoyan.mall.order.dto.StockDto;
import com.cskaoyan.shopping.api.StockApi;
import com.cskaoyan.shopping.converter.CartItemConverter;
import com.cskaoyan.shopping.dal.entitys.Item;
import com.cskaoyan.shopping.dal.persistence.ItemMapper;
import com.cskaoyan.shopping.dto.*;
import com.cskaoyan.shopping.service.ICartService;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author Charadic
 * @since 2022/05/18 22:27
 */
@Service
public class ICartServiceImpl implements ICartService {

    @Autowired
    ItemMapper itemMapper;

    @Autowired
    StockApi stockApi;

    @Autowired
    RedissonClient redissonClient;

    @Override
    public CartListByIdResponse getCartListById(CartListByIdRequest request) {
        CartListByIdResponse cartListByIdResponse = new CartListByIdResponse();

        try {
            request.requestCheck();

            RMap<Long, CartProductDto> map = redissonClient.getMap(String.valueOf(request.getUserId()));

            Collection<CartProductDto> cartProductDtos = map.values();

            List<CartProductDto> list = new ArrayList<>(cartProductDtos);

            cartListByIdResponse.setCartProductDtos(list);
            cartListByIdResponse.setCode(ShoppingRetCode.SUCCESS.getCode());
            cartListByIdResponse.setMsg(ShoppingRetCode.SUCCESS.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            ExceptionProcessorUtils.wrapperHandlerException(cartListByIdResponse, e);
        }

        return cartListByIdResponse;
    }

    @Override
    public AddCartResponse addToCart(AddCartRequest request) {
        AddCartResponse addCartResponse = new AddCartResponse();
        try {
            // 参数校验
            request.requestCheck();
            // 查询商品库存
            StockDto itemStock = stockApi.getItemStock(request.getItemId());
            if(itemStock.getStockCount()<=0){
                addCartResponse.setCode(ShoppingRetCode.ITEM_STOCK_COUNT_ERROR.getCode());
                addCartResponse.setMsg(ShoppingRetCode.ITEM_STOCK_COUNT_ERROR.getMessage());
                return addCartResponse;
            }
            // 查询商品数据
            Item item = itemMapper.selectByPrimaryKey(request.getItemId());

            // 转成Redis存储的Dto
            // 存进Redis
            RMap<Long, CartProductDto> map = redissonClient.getMap(String.valueOf(request.getUserId()));
            CartProductDto productDto = map.get(request.getItemId());
            if (productDto == null) {
                CartProductDto cartProductDto = CartItemConverter.item2Dto(item);
                cartProductDto.setProductNum(Long.valueOf(request.getNum()));
                map.put(request.getItemId(), cartProductDto);
                addCartResponse.setCode(ShoppingRetCode.SUCCESS.getCode());
                addCartResponse.setMsg(ShoppingRetCode.SUCCESS.getMessage());
                return addCartResponse;
            }
            CartProductDto cartProductDto = CartItemConverter.item2Dto(item);
            cartProductDto.setProductNum(productDto.getProductNum() + 1);
            map.put(request.getItemId(), cartProductDto);

            // 成功执行
            // 放入数据
            addCartResponse.setCode(ShoppingRetCode.SUCCESS.getCode());
            addCartResponse.setMsg(ShoppingRetCode.SUCCESS.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            ExceptionProcessorUtils.wrapperHandlerException(addCartResponse, e);
        }

        return addCartResponse;
    }

    @Override
    public UpdateCartNumResponse updateCartNum(UpdateCartNumRequest request) {
        UpdateCartNumResponse updateCartNumResponse = new UpdateCartNumResponse();
        try {
            request.requestCheck();

            // 查询商品库存
            StockDto itemStock = stockApi.getItemStock(request.getItemId());
            if(itemStock.getStockCount()<=0){
                updateCartNumResponse.setCode(ShoppingRetCode.ITEM_STOCK_COUNT_ERROR.getCode());
                updateCartNumResponse.setMsg(ShoppingRetCode.ITEM_STOCK_COUNT_ERROR.getMessage());
                return updateCartNumResponse;
            }

            RMap<Long, CartProductDto> map = redissonClient.getMap(String.valueOf(request.getUserId()));
            CartProductDto cartProductDto = map.get(request.getItemId());
            cartProductDto.setProductNum(Long.valueOf(request.getNum()));
            cartProductDto.setChecked(request.getChecked());
            map.put(request.getItemId(), cartProductDto);

            updateCartNumResponse.setCode(ShoppingRetCode.SUCCESS.getCode());
            updateCartNumResponse.setMsg(ShoppingRetCode.SUCCESS.getMessage());

        } catch (Exception e) {
            e.printStackTrace();
            ExceptionProcessorUtils.wrapperHandlerException(updateCartNumResponse, e);
        }

        return updateCartNumResponse;
    }

    /**
     * 全选或者全不选商品
     *
     * @param
     * @return
     * @author tangwei
     * @since 2022/5/20 9:31
     */
    @Override
    public CheckAllItemResponse checkAllCartItem(CheckAllItemRequest request) {

        CheckAllItemResponse checkAllItemResponse = new CheckAllItemResponse();
        try {
            // 参数校验
            request.requestCheck();

            // 获得该用户的购物车
            RMap<Long, CartProductDto> map = redissonClient.getMap(String.valueOf(request.getUserId()));

            Set<Map.Entry<Long, CartProductDto>> entries = map.entrySet();
            for (Map.Entry<Long, CartProductDto> entry : entries) {
                Long key = entry.getKey();
                CartProductDto value = entry.getValue();
                value.setChecked(request.getChecked());

                map.put(key, value);
            }

            // 成功执行
            checkAllItemResponse.setCode(ShoppingRetCode.SUCCESS.getCode());
            checkAllItemResponse.setMsg(ShoppingRetCode.SUCCESS.getMessage());

        } catch (Exception e) {
            e.printStackTrace();
            ExceptionProcessorUtils.wrapperHandlerException(checkAllItemResponse, e);
        }
        return checkAllItemResponse;
    }

    /**
     * 删除购物车中的商品
     *
     * @param
     * @return
     * @author tangwei
     * @since 2022/5/20 9:32
     */
    @Override
    public DeleteCartItemResponse deleteCartItem(DeleteCartItemRequest request) {
        DeleteCartItemResponse deleteCartItemResponse = new DeleteCartItemResponse();

        try {
            request.requestCheck();

            Long itemId = request.getItemId();
            RMap<Long, CartProductDto> map = redissonClient.getMap(String.valueOf(request.getUserId()));

            if (map == null || map.get(itemId) == null) {
                throw new ValidateException(SysRetCodeConstants.DATA_NOT_EXIST.getCode(), SysRetCodeConstants.DATA_NOT_EXIST.getMessage());
            }

            map.remove(request.getItemId());

            deleteCartItemResponse.setCode(ShoppingRetCode.SUCCESS.getCode());
            deleteCartItemResponse.setCode(ShoppingRetCode.SUCCESS.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            ExceptionProcessorUtils.wrapperHandlerException(deleteCartItemResponse, e);
        }
        return deleteCartItemResponse;
    }

    /**
     * 删除购物车中选中的商品
     *
     * @param
     * @return
     * @author tangwei
     * @since 2022/5/20 9:32
     */
    @Override
    public DeleteCheckedItemResposne deleteCheckedItem(DeleteCheckedItemRequest request) {
        DeleteCheckedItemResposne deleteCheckedItemResposne = new DeleteCheckedItemResposne();

        try {
            request.requestCheck();
            RMap<Long, CartProductDto> map = redissonClient.getMap(String.valueOf(request.getUserId()));

            Set<Map.Entry<Long, CartProductDto>> entries = map.entrySet();
            for (Map.Entry<Long, CartProductDto> entry : entries) {
                if ("true".equals(entry.getValue().getChecked())) {
                    map.remove(entry.getKey());
                }
            }

            deleteCheckedItemResposne.setCode(ShoppingRetCode.SUCCESS.getCode());
            deleteCheckedItemResposne.setMsg(ShoppingRetCode.SUCCESS.getMessage());

        } catch (Exception e) {
            e.printStackTrace();
            ExceptionProcessorUtils.wrapperHandlerException(deleteCheckedItemResposne, e);
        }

        return deleteCheckedItemResposne;
    }

    /**
     * lxc
     * 下单后清空购物车
     *
     * @param request
     * @return
     */
    @Override
    public ClearCartItemResponse clearCartItemByUserID(ClearCartItemRequest request) {
        ClearCartItemResponse clearCartItemResponse = new ClearCartItemResponse();
        List<Long> productIds = request.getProductIds();

        try {
            request.requestCheck();

            RMap<Long, CartProductDto> map = redissonClient.getMap(String.valueOf(request.getUserId()));

            Set<Map.Entry<Long, CartProductDto>> entries = map.entrySet();
            for (Map.Entry<Long, CartProductDto> entry : entries) {
                for (Long productId : productIds) {
                    if (productId.equals(entry.getValue().getProductId())) {
                        map.remove(entry.getKey());
                    }
                }
            }

            clearCartItemResponse.setCode(ShoppingRetCode.SUCCESS.getCode());
            clearCartItemResponse.setMsg(ShoppingRetCode.SUCCESS.getMessage());

        } catch (Exception e) {
            e.printStackTrace();
            ExceptionProcessorUtils.wrapperHandlerException(clearCartItemResponse, e);
        }

        return clearCartItemResponse;
    }
}
